package cn.sytton.taffe.framework.security.sms.code;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.sytton.taffe.framework.factory.RedisUtil;
import cn.sytton.taffe.framework.constants.RedisKey;
import cn.sytton.taffe.framework.exception.BizException;
import cn.sytton.taffe.framework.properties.auth.AuthProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.LinkedHashMap;
import java.util.concurrent.TimeUnit;

/**
 * 短信验证码工厂
 *
 * @author skyrock
 */
@Slf4j
@Component
public class SmsCodeFactory {

    @Resource
    private AuthProperties authProperties;

    @Resource
    private RedisUtil redisUtil;

    private ILoginSmsCode loginSmsCode;

    public SmsCodeFactory(@Nullable ILoginSmsCode loginSmsCode) {
        if (loginSmsCode == null) {
            log.debug("发送短信验证码的实现类(ILoginSmsCode)=null");
        } else {
            this.loginSmsCode = loginSmsCode;
        }
    }

    /**
     * 创建code
     * @param cellphone 手机号码
     * @return SMS对象
     */
    public SmsCode create(String cellphone) {
        SmsCode sms = new SmsCode();
        sms.setCellphone(cellphone);
        sms.setCode(RandomUtil.randomNumbers(6));
        sms.setGenerateTime(System.currentTimeMillis());
        return sms;
    }

    /**
     * 创建code并且发送出去
     * @param cellphone 手机号码
     * @return SMS对象
     */
    public SmsCode createAndSend(String cellphone) {
        SmsCode sms = create(cellphone);
        if (loginSmsCode != null) {
            LinkedHashMap<String, Object> params = new LinkedHashMap<>();
            params.put(authProperties.getSms().getParamName(), sms.getCode());
            String requestId = loginSmsCode.send(cellphone, params);
            log.debug("获取短信验证码返回requestId="+requestId);
            if (StringUtils.hasText(requestId)) {
                save(sms);
                return sms;
            } else {
                throw new BizException("获取短信验证码失败");
            }
        } else {
            return sms;
        }
    }

    /**
     * 保存code
     * @param sms 验证码对象
     */
    public void save(SmsCode sms) {
        redisUtil.setObject(getCellphoneKey(sms.getCellphone()), sms.getCode(), authProperties.getSms().getExpireTime(), TimeUnit.MINUTES);
    }

    /**
     * 验证code
     * @param cellphone 手机号
     * @param code 验证的code
     * @return true/false
     */
    public boolean verify(String cellphone, String code) {
        if (StringUtils.hasText(cellphone) && StringUtils.hasText(code)) {
            Object originCode = redisUtil.getObject(getCellphoneKey(cellphone));
            if (originCode != null) {
                return originCode.toString().equalsIgnoreCase(code);
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    /**
     * 删除用户身份信息
     */
    public void delSms(String cellphone) {
        if (StrUtil.isNotEmpty(cellphone)) {
            redisUtil.deleteObject(getCellphoneKey(cellphone));
        }
    }

    private String getCellphoneKey(String cellphone) {
        return RedisKey.LOGIN_CELLPHONE_KEY + cellphone;
    }
}
